package com.lyeducation.core.base.TreeEntityService;

import com.lyeducation.entities.base.BaseTreeEntity;

import java.util.*;

public class UpDownTreeEntityServiceImpl<E extends BaseTreeEntity>
        implements UpDownTreeEntityService<E> {

    public static <E extends BaseTreeEntity> UpDownTreeEntityService<E> createUpDownTreeEntityService(
            Class<E> clazz) {
        return new UpDownTreeEntityServiceImpl<E>();
    }

    @Override
    public TreeSet<E> upDownTreeEntity(List<E> treeEntityCollection) {
        if (treeEntityCollection.size() > 1) {
            HashSet<E> vertexSet = new HashSet<E>();
            //      还是要考虑多个顶级菜单
            //      菜单集合剩余都是顶点菜单集则排序结束

            while (!vertexSet.containsAll(treeEntityCollection)) {
                E vertexBaseTreeEntity = null;
                for (int i = 0; i < treeEntityCollection.size(); i++) {
                    vertexBaseTreeEntity = treeEntityCollection.get(i);
                    if (!vertexSet.contains(vertexBaseTreeEntity)) {
                        break;
                    }
                }
                //        顶点菜单赋予其所有下级菜单并从菜单集合去除其所有下级菜单
                setChildren(vertexBaseTreeEntity, treeEntityCollection);
                
                //     首选顶点菜单可能会存在上级需要重新加回来
                //                treeEntityCollection.add(vertexBaseTreeEntity);

                //        每个作为顶点菜单都有可能包含之前所有作为顶点菜单的顶点
                //        检验顶点菜单集合是否有被作其上级顶点菜单包含了
                Iterator<E> vertexBaseTreeEntityIterator = vertexSet.iterator();
                while (vertexBaseTreeEntityIterator.hasNext()) {
                    BaseTreeEntity checkVertexBaseTreeEntity = vertexBaseTreeEntityIterator.next();
                    //          如果剩余菜单已经不存在顶点菜单则已经有其上级顶点菜单包含了需要移除其作为顶点菜单资格
                    if (!treeEntityCollection.contains(checkVertexBaseTreeEntity)) {
                        vertexBaseTreeEntityIterator.remove();
                    }
                }
                //        新顶点菜单
                vertexSet.add(vertexBaseTreeEntity);
            }

            TreeSet<E> realVertexSet =
                    new TreeSet<E>(
                            new Comparator<E>() {
                                @Override
                                public int compare(E o1, E o2) {
                                    if (o2.getId().equals(o1.getId())) {
                                        return 0;
                                    }
                                    if (o1.getSort() - o2.getSort() == 0) {
                                        return 1;
                                    }
                                    return o1.getSort() - o2.getSort();
                                }
                            });
            realVertexSet.addAll(vertexSet);
            return realVertexSet;
        }
        return null;
    }

    @Override
    public void setChildren(E upLevelBaseTreeEntity, Collection<E> treeEntityList) {
        //        TreeSet<E> childSet = upLevelBaseTreeEntity.getChildren();
        //        if (childSet == null) {
        //            upLevelBaseTreeEntity.setChildren(null);
        //            childSet = upLevelBaseTreeEntity.getChildren();
        //        }
        //        for (E children : treeEntityList) {
        //            if (children.getParentId() != null
        //                    && children.getParentId().equals(upLevelBaseTreeEntity.getId())) {
        //                childSet.add(children);
        //            }
        //        }
        //        treeEntityList.remove(upLevelBaseTreeEntity);
        //        if (childSet.size() == 0) {
        //            return;
        //        }
        //        for (E nextParent : childSet) {
        //            setChildren(nextParent, treeEntityList);
        //        }
        if (upLevelBaseTreeEntity.getChildren() == null) {
            upLevelBaseTreeEntity.setChildren(null);
        }
        Iterator<E> iterator = treeEntityList.iterator();
        while (iterator.hasNext()) {
            E children = iterator.next();
            if (upLevelBaseTreeEntity.getId().equals(children.getParentId())) {
                upLevelBaseTreeEntity.getChildren().add(children);
                iterator.remove();
            }
        }
        TreeSet<E> upLevelBaseTreeEntityChildren = upLevelBaseTreeEntity.getChildren();
        if (upLevelBaseTreeEntityChildren == null) {
            return;
        }
        for (E sysRoleEntity : upLevelBaseTreeEntityChildren) {
            setChildren(sysRoleEntity, treeEntityList);
        }
    }
}
